#ifndef LONGPOLLSDK_H
#define LONGPOLLSDK_H
#include "longpoll_api.h"
#include "fasterhttp.h"
#include "threadpool.h"
#include "uhp_idl.h"
#include "uhp_util.h"
#include <string>
#include <sys/epoll.h>
#include <vector>
#include <set>
#include <algorithm>
#include <sys/prctl.h>
using std::string;
using std::vector;
using std::set;
#define GETNETADDRESS_LOCAL(_netaddr_) \
	{ \
		socklen_t       socklen = sizeof(struct sockaddr) ; \
		int             nret = 0 ; \
		nret = getsockname( (_netaddr_).sock , (struct sockaddr*)&((_netaddr_).local_addr) , & socklen ) ; \
		if( nret == 0 ) \
		{ \
			strcpy( (_netaddr_).local_ip , inet_ntoa((_netaddr_).local_addr.sin_addr) ); \
			(_netaddr_).local_port = (int)ntohs( (_netaddr_).local_addr.sin_port ) ; \
		} \
	}


#define LONG_POLL_SDK_FUSING_TIME	60
#define LONG_POLL_SDK_FULL_FUSING_TIME	10
#define LONG_POLL_CONNECT_TIME		5

const int OnNotifyTimeout = 10;
struct HostInfo
{
	char	ip[15];
	int	port;
	long	activeTimestamp;
};

int connectNonBlock(int connect_timeout, struct NetAddress* p_addr);

int WriteAlertLog( char *c_filename , long c_fileline , int log_level, char *format , ... );
#define ALERTERRORLOG( ... ) \
do{ \
        WriteErrorLogsG( __FILE__ , __LINE__ , ##__VA_ARGS__ ); \
        WriteAlertLog( __FILE__ , __LINE__ , LOG_LEVEL_ERROR, ##__VA_ARGS__); \
}while(0)

#define ALERT_PLAT_LONGPOLL_ERRORCODE_APPCODE              "@ALERT{PLATFORM}{LONGPOLL}{%d}{%s}"
#define LONGPOLLALERTERRORLOG( ... ) \
do{ \
        ALERTERRORLOG(ALERT_PLAT_LONGPOLL_ERRORCODE_APPCODE  __VA_ARGS__ ); \
        NOTICELOGSG( ALERT_PLAT_LONGPOLL_ERRORCODE_APPCODE  __VA_ARGS__ ); \
}while(0)

void SetLoglevel( char* p_loglevel );
int InitLogEnv( );
int InitLogEnv_Format( char *service_name , char *module_name , char *event_output , int process_loglevel , char* host_name, char* user_name, char *process_output_format ,
... );
int InitLogEnvV( char *service_name , char *module_name , char *event_output , int process_loglevel , char* host_name, char* user_name, char *process_output_format , va_list valist );
void CleanLogEnv();

class LongPoll {
public:
	LongPoll(int longpoll_timeout, char* p_servers, ConstructLongPollDUPReqFn ConstructLongPollDUPReq, OnNotifyFn OnNotify, AfterNotifyCB pCallback, void* arg, void* reserve);
	~LongPoll();
	int StartLongPollAsync();
	int StartLongPoll();
	int StopLongPoll();
	
	bool 			g_exit_flag;
	bool			g_on_notify_flag;
	bool 			g_rebalance_flag;
	void*			reserve;
	void*			arg;
	struct HostInfo*	p_current_host;
	int			client_port;
	string			client_id;
	string			client_ip;

private:
	threadpool_t*		thread_pool;
	pthread_t		longpoll_thread;

	int			longpoll_timeout;
	int			svrCount;
	struct HostInfo		svrList[100];
	
	static void* StartLongPollStatic(void*);
	int OnNotifyWrap(HttpEnv* http);	
	struct HostInfo* ChooseRandomHost();
	void SetServiceHosts(char* p_servers);	
	int InitClientId();
	ConstructLongPollDUPReqFn ConstructLongPollDUPReq;
	OnNotifyFn OnNotify;
	AfterNotifyCB pCallback;
};

#endif // LONGPOLLSDK_H
